package robocup.component.speechacts.coachlanguage;

import java.util.LinkedList;

import robocup.component.ControllerNumbers.PLAY_MODE;

public class Condition {

  private TypeConstants.CONDITIONTYPE conditionType = TypeConstants.CONDITIONTYPE.INIT;

  private String                      conditionName = "";

  private String                      clangStr      = "";

  private PLAY_MODE                   playMode      = PLAY_MODE.UNKNOWN;

  private String                      unumString    = "";

  private int                         unumInt       = 0;

  private UnumSet                     unumSet       = null;

  private boolean                     teamOur       = false;

  private Region                      region        = null;

  private int                         pposInt1      = 0;

  private int                         pposInt2      = 0;

  private Condition                   not           = null;

  private LinkedList<Condition>       and           = new LinkedList<Condition>();

  private LinkedList<Condition>       or            = new LinkedList<Condition>();

  private String                      condComp      = "";

  private int                         condCompInt   = 0;

  private TypeConstants.CONDCOMPTYPE  condCompType  = TypeConstants.CONDCOMPTYPE.INIT;

  public void addAnd(final Condition condition) {

    this.and.add(condition);
  }

  public void addOr(final Condition condition) {

    this.or.add(condition);
  }

  public String getConditionName() {

    return this.conditionName;
  }

  public void setConditionName(final String conditionName) {

    this.conditionName = conditionName;
  }

  public TypeConstants.CONDITIONTYPE getConditionType() {

    return this.conditionType;
  }

  public void setConditionType(final TypeConstants.CONDITIONTYPE conditionType) {

    this.conditionType = conditionType;
  }

  public String getClangStr() {

    return this.clangStr;
  }

  public void setClangStr(final String clangStr) {

    this.clangStr = clangStr;
  }

  public PLAY_MODE getPlayMode() {

    return this.playMode;
  }

  public void setPlayMode(final PLAY_MODE playMode) {

    this.playMode = playMode;
  }

  public UnumSet getUnumSet() {

    return this.unumSet;
  }

  public void setUnumSet(final UnumSet unumSet) {

    this.unumSet = unumSet;
  }

  public String getUnumString() {

    return this.unumString;
  }

  public void setUnumString(final String unumString) {

    this.unumString = unumString;
  }

  public boolean isTeamOur() {

    return this.teamOur;
  }

  public void setTeamOur(final boolean teamOur) {

    this.teamOur = teamOur;
  }

  public Region getRegion() {

    return this.region;
  }

  public void setRegion(final Region region) {

    this.region = region;
  }

  public int getPposInt1() {

    return this.pposInt1;
  }

  public void setPposInt1(final int pposInt1) {

    this.pposInt1 = pposInt1;
  }

  public int getPposInt2() {

    return this.pposInt2;
  }

  public void setPposInt2(final int pposInt2) {

    this.pposInt2 = pposInt2;
  }

  public Condition getNot() {

    return this.not;
  }

  public void setNot(final Condition not) {

    this.not = not;
  }

  public LinkedList<Condition> getAnd() {

    return this.and;
  }

  public void setAnd(final LinkedList<Condition> and) {

    this.and = and;
  }

  public LinkedList<Condition> getOr() {

    return this.or;
  }

  public void setOr(final LinkedList<Condition> or) {

    this.or = or;
  }

  public String getCondComp() {

    return this.condComp;
  }

  public void setCondComp(final String condComp) {

    this.condComp = condComp;
  }

  public int getCondCompInt() {

    return this.condCompInt;
  }

  public void setCondCompInt(final int condCompInt) {

    this.condCompInt = condCompInt;
  }

  public TypeConstants.CONDCOMPTYPE getCondCompType() {

    return this.condCompType;
  }

  public void setCondCompType(final TypeConstants.CONDCOMPTYPE condCompType) {

    this.condCompType = condCompType;
  }

  public int getUnumInt() {

    return this.unumInt;
  }

  public void setUnumInt(final int unumInt) {

    this.unumInt = unumInt;
  }

  private String playModeToString() {

    final StringBuffer buf = new StringBuffer();

    switch (this.playMode) {

      case BEFORE_KICK_OFF:
        buf.append("bko");
        break;

      case TIME_OVER:
        buf.append("time_over");
        break;

      case PLAY_ON:
        buf.append("play_on");
        break;

      case KICK_OFF_OWN:
        buf.append("ko_our");
        break;

      case KICK_OFF_OTHER:
        buf.append("ko_opp");
        break;

      case KICK_IN_OWN:
        buf.append("ki_our");
        break;

      case KICK_IN_OTHER:
        buf.append("ki_opp");
        break;

      case FREE_KICK_OWN:
        buf.append("fk_our");
        break;

      case FREE_KICK_OTHER:
        buf.append("fk_opp");
        break;

      case CORNER_KICK_OWN:
        buf.append("ck_our");
        break;

      case CORNER_KICK_OTHER:
        buf.append("ck_opp");
        break;

      case GOAL_KICK_OWN:
        buf.append("gk_our");
        break;

      case GOAL_KICK_OTHER:
        buf.append("gk_opp");
        break;

      case GOAL_OWN:
        buf.append("gc_our");
        break;

      case GOAL_OTHER:
        buf.append("gc_opp");
        break;

    }

    return buf.toString();
  }

  private String condCompToString() {

    final StringBuffer buf = new StringBuffer();

    switch (this.getCondCompType()) {

      case TIME:
        buf.append("time " + this.condComp + " " + this.condCompInt);
        break;

      case OPP_GOALS:
        buf.append("opp_goals " + this.condComp + " " + this.condCompInt);
        break;

      case OUR_GOALS:
        buf.append("our_goals " + this.condComp + " " + this.condCompInt);
        break;

      case GOAL_DIFF:
        buf.append("goal_diff " + this.condComp + " " + this.condCompInt);
        break;

    }
    return buf.toString();

  }

  @Override
  public String toString() {

    final StringBuffer buf = new StringBuffer();

    switch (this.getConditionType()) {

      case INIT:
        buf.append("(empty condition)");
        break;

      case NAME:
        buf.append(this.conditionName);
        break;

      case FALSE:
        buf.append("(false)");
        break;

      case TRUE:
        buf.append("(true)");
        break;

      case PLAYM:
        buf.append("(playm " + this.playModeToString() + ")");
        break;

      case UNUM:
        buf.append("(unum " + this.unumString + this.unumSet.toString() + ")");
        break;

      case BOWNER:
        buf.append("(bowner ");
        if (this.teamOur) {
          buf.append("our");
        }
        else {
          buf.append("opp");
        }
        buf.append(this.unumSet.toString() + ")");
        break;

      case BPOS:
        buf.append("(bpos " + this.region.toString() + ")");
        break;

      case PPOS:
        buf.append("(ppos ");
        if (this.teamOur) {
          buf.append("our");
        }
        else {
          buf.append("opp");
        }
        buf.append(this.unumSet.toString() + " ");
        buf.append(this.pposInt1 + " " + this.pposInt2 + " ");
        buf.append(this.region.toString() + ")");
        break;

      case NOT:
        buf.append("(not ");
        buf.append(this.not + ")");
        break;

      case AND:
        buf.append("(and");
        for (final Condition cond : this.and) {
          buf.append(" " + cond.toString());
        }
        buf.append(")");
        break;

      case OR:
        buf.append("(or");
        for (final Condition cond : this.or) {
          buf.append(" " + cond.toString());
        }
        buf.append(")");
        break;

      case CONDCOMP:
        buf.append("(" + this.condCompToString() + ")");
        break;

    }

    return buf.toString();

  }

}
